/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package flightlifter;

import java.nio.FloatBuffer;
import java.util.Vector;
import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.GL11;

/**
 *
 * @author Matt
 */
public class LineEngine extends Node implements WiringConsumer {

    float throttle = 0;
    private float maxThrust = 50; //in Newtons
    private PVector dir = new PVector();
    int count = 0;
    ParticleSystem exhaust = new ParticleSystem();
    OrthoNormalBasis ONB;
    MeshLoader[] meshLoader;
    float cnt = 0;
    float bladeRot = 0;

    public LineEngine(OrthoNormalBasis ONB, MeshLoader[] meshLoader) {

        this.ONB = ONB;
        this.meshLoader = meshLoader;
    }

    public void throttleAdd(float add) {
        throttle -= add;
        if (throttle > maxThrust) {
            throttle = maxThrust;
        }
        if (throttle < 0) {
            throttle = 0;
        }
    }



    public void render(int mode) {

        cnt++;



        if (selected == 1) {
            GL11.glColor3f(1.0f, 1.0f, 0.0f);
        } else {
            GL11.glColor3f(.75f, 0.75f, 0.75f);
        }

        GL11.glLineWidth(64.f);
        GL11.glBegin(GL11.GL_LINE_LOOP);                    // Drawing Using Triangles
        GL11.glVertex3f(ONB.front.pos.x, ONB.front.pos.y, ONB.front.pos.z);
        GL11.glVertex3f(ONB.middle.pos.x, ONB.middle.pos.y, ONB.middle.pos.z);
        GL11.glEnd();

        //ONB.update();

        GL11.glPushMatrix();
        PVector rot = ONB.getForwardCentroid();
        GL11.glTranslatef(rot.x, rot.y, rot.z);
        
        
        if (mode == FlightLifter.QUAD_RENDER){
            GL11.glColor4f(1, 1, 1, .25f);
                    GL11.glDisable(GL11.GL_DEPTH_TEST);
        }
        else{
            GL11.glColor4f(1, 1, 1, 1f);
        }



        //I don't understand the code below.
        //it was a shot in the dark from
        //staring at the gluLookat code.
        //matrices are scary...it works

        //here be dragons

        PVector u = ONB.getUp();
        u.normalize();

        PVector r = ONB.getRight();
        r.normalize();

        PVector f = ONB.getForward();
        f.normalize();

        float[] temp = {r.x, r.y, r.z, 0,
            u.x, u.y, u.z, 0,
            f.x, f.y, f.z, 0,
            0, 0, 0, 1.f};

        FloatBuffer model = FlightLifter.allocFloats(temp);
        GL11.glPushMatrix();

        GL11.glMultMatrix(model);
        meshLoader[0].draw();
        GL11.glPopMatrix();
        GL11.glTranslatef(5 * f.x, 5 * f.y, 5 * f.z);
        GL11.glMultMatrix(model);

        GL11.glRotatef(bladeRot, 0, 0, 1);

        GL11.glScalef(1.4f, 1.4f, 1.4f);

        //GL11.glTranslatef(ONB.front.pos.x, ONB.front.pos.y, ONB.front.pos.z);
        meshLoader[1].draw();

        GL11.glPopMatrix();
        // exhaust.render();
        GL11.glEnable(GL11.GL_DEPTH_TEST);
    }

    public void physics() {

        //apply engine force
        //get direction we are facing

        bladeRot -= throttle;

        dir = ONB.getForward();
        float vel = dir.mag();
        dir.div(vel);

        //this applies the engine thrust to the attached particles
        dir.mult(throttle * maxThrust / 2.f);

        ONB.front.impulse(dir.get());
        ONB.middle.impulse(dir.get());



        /*

        //update the exhaust system for this particle system
        exhaust.physics();

        for (int i = 0; i < 10; i++) {
        PVector dir2 = ONB.getForward();
        dir2.mult(-1.f);




        PVector smooth = ONB.getForward();
        smooth.mult(-(float)Math.random());
        smooth.add(ONB.middle.pos.get());

        exhaust.particles.add(new Particle(smooth,
        dir2,
        (float) Math.random() * 90, (float) Math.random() * 5,
        (float) Math.random() * 90, (float) Math.random() * 5,
        (float) Math.random() * 90, (float) Math.random() * 5, (int) (Math.random() * 500)));

        }

         */



    }

    public LineEngine(String[] line, Vector<Node> nodes, MeshLoader[] engineMesh) {
        this(new OrthoNormalBasis((Point) nodes.elementAt(Integer.parseInt(line[1])),
                (Point) nodes.elementAt(Integer.parseInt(line[2])),
                (Point) nodes.elementAt(Integer.parseInt(line[3]))),
                engineMesh);


    }

    public String pickle(Vector<Node> nodes) {
        return "E,"
                + ONB.pickle(nodes);


    }

    @Override
    public void setValue(float value) {
        throttleAdd(value / 20);


    }

    @Override
    public PVector getScreenCenter() {
        return getScreenSpaceCentroid();


    }

    @Override
    public boolean dependsOn(Point p) {
        return false;

    }

    @Override
    public PVector getCentroid() {
        return ONB.getCentroid();


    }

    @Override
    public PVector getScreenSpaceCentroid() {
        PVector tmp = getCentroid();
        float[] ret = GLProject.project(tmp.x, tmp.y, tmp.z);

        return new PVector(ret[0], ret[1], 0);

    }
}
